﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Wordprocessing;

namespace component
{
    public partial class DocxBuilderComponent
    {
        //просматириваем линейные элементы
        public static List<OpenXmlElement> inlineElement(XmlNode element)
        {
            //список линейных элементов
            List<OpenXmlElement> listInlineElement = new List<OpenXmlElement>();

            switch (element.Name)
            {
                case "application":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "Application"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "codeInline":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "CodeInline"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "command":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "Command"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "computerOutputInline":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "ComputerOutputInline"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "database":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "Database"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "environmentVariable":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "EnvironmentVariable"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "errorInline":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "ErrorInline"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "fictitiousUri":
                    {
                        foreach (Run el in createInlineRun(element, "FictitiousUri"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "foreignPhrase":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "ForeignPhrase"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "hardware":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "Hardware"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "legacyBold":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "LegacyBold"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "legacyItalic":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "LegacyItalic"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "legacyUnderline":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "LegacyUnderline"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "literal":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "Literal"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "localUri":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "LocalUri"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "mediaLinkInline":
                    {
                        if (element.HasChildNodes)
                        {
                            foreach (XmlNode image in element)
                            {
                                if (image.NodeType == XmlNodeType.Element && image.Name == "image")
                                {
                                    listInlineElement.Add(getDrawing(image));
                                }
                            }
                        }

                    }
                    break;
                case "markup":
                    {
                    }
                    break;
                case "math":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "Math"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "newTerm":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "NewTerm"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "phrase":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "Phrase"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "placeholder":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "Placeholder"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "quoteInline":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "QuoteInline"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "replaceable":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "Replaceable"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "subscript":
                    {
                        foreach (XmlNode node in element)
                        {
                            if (node.NodeType == XmlNodeType.Text)
                            {
                                char[] splits = { '\n', '\r', '\t', ' ' };
                                string[] para = node.Value.Split(splits);
                                string outStr = "";
                                foreach (string str in para)
                                {
                                    if (str != "")
                                        outStr += str.PadRight(str.Length + 1, ' ');
                                }

                                if (outStr != "")
                                {
                                    Run r = new Run();
                                    RunProperties rPr = new RunProperties();
                                    VerticalTextAlignment vertTextAlegm = new VerticalTextAlignment() { Val = VerticalPositionValues.Subscript };
                                    rPr.Append(vertTextAlegm);
                                    r.Append(rPr);
                                    Text text = new Text() { Space = SpaceProcessingModeValues.Preserve };
                                    text.Text = outStr;
                                    r.Append(text);

                                    listInlineElement.Add(r);
                                }
                            }
                        }
                    }
                    break;
                case "superscript":
                    {
                        foreach (XmlNode node in element)
                        {
                            if (node.NodeType == XmlNodeType.Text)
                            {
                                char[] splits = { '\n', '\r', '\t', ' ' };
                                string[] para = node.Value.Split(splits);
                                string outStr = "";
                                foreach (string str in para)
                                {
                                    if (str != "")
                                        outStr += str.PadRight(str.Length + 1, ' ');
                                }

                                if (outStr != "")
                                {
                                    Run r = new Run();
                                    RunProperties rPr = new RunProperties();
                                    VerticalTextAlignment vertTextAlegm = new VerticalTextAlignment() { Val = VerticalPositionValues.Subscript };
                                    rPr.Append(vertTextAlegm);
                                    r.Append(rPr);
                                    Text text = new Text() { Space = SpaceProcessingModeValues.Preserve };
                                    text.Text = outStr;
                                    r.Append(text);

                                    listInlineElement.Add(r);
                                }
                            }
                        }
                    }
                    break;
                case "system":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "System"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "ui":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "Ui"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "unmanagedCodeEntityReference":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "UnmanagedCodeEntityReference"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "userInput":
                    {
                        foreach (OpenXmlElement el in createInlineRun(element, "UserInput"))
                            listInlineElement.Add(el);
                    }
                    break;
                case "link":
                    {
                        if (element.Attributes.Count != 0)
                        {
                            string linkHref = element.Attributes["xlink:href"].InnerText;

                            if (!linkHref.Contains("#"))
                            {
                                foreach (string topicId in topicTitleAndId.Keys)
                                {
                                    if (linkHref == topicId)
                                    {
                                        string[] partTopicId = topicId.Split('-');
                                        Hyperlink hyperlink = new Hyperlink() { History = true, Anchor = "topicId_" + partTopicId[0] };

                                        Run r = new Run();
                                        RunProperties rPr = new RunProperties();
                                        RunStyle rStyle = new RunStyle() { Val = "Token" };
                                        rPr.Append(rStyle);
                                        r.Append(rPr);
                                        Text text = new Text() { Space = SpaceProcessingModeValues.Preserve };
                                        text.Text = topicTitleAndId[topicId];
                                        r.Append(text);

                                        hyperlink.Append(r);
                                        listInlineElement.Add(hyperlink);
                                        break;
                                    }
                                }
                            }

                            if (String.IsNullOrEmpty(linkHref) && element.HasChildNodes)
                            {
                                foreach (XmlNode element2 in element)
                                {
                                    if (element2.NodeType == XmlNodeType.Text)
                                    {
                                        char[] splits = { '\n', '\r', '\t', ' ' };
                                        string[] para = element2.Value.Split(splits);
                                        string outStr = "";
                                        foreach (string str in para)
                                        {
                                            if (str != "")
                                                outStr += str.PadRight(str.Length + 1, ' ');
                                        }

                                        Run r = new Run();
                                        Text text = new Text() { Space = SpaceProcessingModeValues.Preserve };
                                        text.Text = outStr;
                                        r.Append(text);
                                        listInlineElement.Add(r);
                                    }
                                }
                            }
                        }
                    }
                    break;
                case "token":
                    {
                        if (DocxBuilderComponent.tokenIdAndName.Count != 0)
                        {
                            foreach (string tokenId in DocxBuilderComponent.tokenIdAndName.Keys)
                            {
                                if (element.InnerText == tokenId)
                                {
                                    if (DocxBuilderComponent.tokenIdAndName[tokenId].StartsWith("#hiperlink#"))
                                    {
                                        string txt = DocxBuilderComponent.tokenIdAndName[tokenId].Remove(0, 11);
                                        Run r = new Run();
                                        RunProperties rPr = new RunProperties();
                                        RunStyle rStyle = new RunStyle() { Val = "Token" };
                                        rPr.Append(rStyle);
                                        r.Append(rPr);
                                        Text text = new Text() { Space = SpaceProcessingModeValues.Preserve };
                                        text.Text = txt;
                                        r.Append(text);

                                        Hyperlink hyperlink = new Hyperlink() { History = true, Id = tokenId };
                                        hyperlink.Append(r);
                                        listInlineElement.Add(hyperlink);
                                    }

                                    else
                                    {
                                        Run r = new Run();
                                        Text text = new Text() { Space = SpaceProcessingModeValues.Preserve };
                                        text.Text = DocxBuilderComponent.tokenIdAndName[tokenId];
                                        r.Append(text);
                                        listInlineElement.Add(r);
                                    }
                                }
                            }
                        }
                    }
                    break;
            }
            return listInlineElement;
        }

        //добавление в параграф линейного элемента
        public static List<OpenXmlElement> createInlineRun(XmlNode inlineNode, string style)
        {
            List<OpenXmlElement> listcreateInlineRun = new List<OpenXmlElement>();
            foreach (XmlNode element in inlineNode)
            {
                if (element.NodeType == XmlNodeType.Text)
                {
                    Run r = new Run();
                    RunProperties rPr = new RunProperties();
                    RunStyle rStyle = new RunStyle() { Val = style };
                    rPr.Append(rStyle);
                    r.Append(rPr);
                    Text text = new Text() { Space = SpaceProcessingModeValues.Preserve };
                    text.Text = removeSingles(element.Value);
                    r.Append(text);

                    listcreateInlineRun.Add(r);
                }

                if (element.NodeType == XmlNodeType.Element)
                {
                    foreach (OpenXmlElement el in inlineElement(element))
                        listcreateInlineRun.Add(el);
                }
            }

            return listcreateInlineRun;
        }
    }
}
